package ro.gillardon.business.polling;

import java.time.LocalDateTime;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.ScheduleExpression;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.Timeout;
import javax.ejb.TimerService;

import org.apache.log4j.Logger;

import ro.gillardon.commons.hotel.HotelDetailsWrapper;
import ro.gillardon.commons.logger.BTPLogger;
import ro.gillardon.persistence.DAOFactory;
import ro.gillardon.persistence.HotelDetailsDAO;
import ro.gillardon.persistence.exception.PersistenceException;

/**
 * Timer class for hotels. Every day at 00:01 the polling services will be called.
 *
 * @author lorinczi
 */
@Singleton
@Startup
public class HotelPollingTimer {

  /**
   * Timer service.
   */
  @Resource
  transient private TimerService timerService;

  /**
   * Log4j logging.
   */
  private static final Logger LOG = Logger.getLogger(HotelPollingTimer.class);

  /**
   * Constructor without fields.
   */
  public HotelPollingTimer() {
    super();
  }

  /**
   * Post Constructor initializations. Every day at 00:01 will trigger.
   */
  @PostConstruct
  public void initialize() {
    ScheduleExpression expression = new ScheduleExpression();
    expression.minute("1").hour("0");
    this.timerService.createCalendarTimer(expression);
  }

  /**
   * Timeout method, calls the hotel parsers.
   */
  @Timeout
  public static void execute() {

    HotelDetailsWrapper achatBrettenWrapper = AchatBrettenParser.getLatestPrice();
    saveHotelDetailsWrapper(achatBrettenWrapper);
    HotelDetailsWrapper commundoIsmaningWrapper = CommundoIsmaningParser.getLatestPrice();
    saveHotelDetailsWrapper(commundoIsmaningWrapper);

    logInfoDateTime();
  }

  private static void logInfoDateTime() {
    LocalDateTime date = LocalDateTime.now();
    BTPLogger.info(LOG, "TimerService at" + date.getHour() + ":" + date.getMinute() + " " + date.getDayOfMonth()
      + "/" + date.getMonthValue() + "/" +
      date.getYear());
  }

  private static void saveHotelDetailsWrapper(final HotelDetailsWrapper hotelWrapper) {
    if (hotelWrapper == null) {
      BTPLogger.error(LOG, "Error: hoteWarapper null");
    } else {
      HotelDetailsDAO hd = DAOFactory.getDAOFactory().getHotelDetailsDAO();
      try {
        hd.save(hotelWrapper);
      } catch (PersistenceException e) {
        BTPLogger.error(LOG, "Error: cant save " + hotelWrapper.getHotel().getName() + " in db. Details: " + e);
      }
    }
  }
}
